import 'dart:async';
import 'dart:convert';

import 'package:fluro/fluro.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_base_lib/flutter_base_lib.dart';

class M7Route {
  M7Route._();

  /// *********************************** 静态属性 ***********************************
  ///全局Router 调用初始化后必须赋值
  static late final FluroRouter router;

  /// 全局导航栈的内部路由下标 计数 (私有的静态属性,防止外部篡改)
  static int _navigationStackIndex = 0; // 0 代表路由栈下标为0的路由, 既是栈底,也是栈顶.
  /// *********************************** 私有的静态基础导航函数 ***********************************
  /// 万恶之首，初始化，必须的
  static FluroRouter configureRoutes() {
    router = FluroRouter();
    router.notFoundHandler = Handler(handlerFunc: (BuildContext? context, Map<String, List<String>> params) {
      M7Log.e(msg: "----------------------Page 404----------------------");
      return;
    });
    return router;
  }

  static _navigationStackIndexPlus(bool replace, bool clearStack) {
    if (replace) {
    } else if (clearStack) {
      _navigationStackIndex = 0;
    } else {
      _navigationStackIndex += 1;
    }
  }

  /// 导航栈下标 minus
  static _navigationStackIndexMinus(bool replace, bool clearStack) {
    if (replace) {
      // replace 不变
    } else if (clearStack) {
      // clearStack 下标归零(navigate.to 的新的路由既为栈底,也为栈底 对应下标就是0)
      _navigationStackIndex = 0;
    } else {
      // 导航跳转失败, 撤回跳转前新增的计数
      if (_navigationStackIndex > 0) {
        _navigationStackIndex -= 1;
      }
    }
  }

// 讲路由路径和需要传递的参数进行拼装
  /// 返回格式为 {params:String} 将Map<T>类型的params json序列化传递出去
  static _routerNameMixWithParams(String routerName, Map<String, dynamic>? params) {
    if (params == null || params.isEmpty) {
      return routerName;
    } else {
      routerName = routerName;
      String jsonParams = Uri.encodeComponent(jsonEncode(params));
      M7Log.d(msg: jsonParams);
      return routerName + '?' + "params=$jsonParams";
    }
  }

  /// 讲路由路径和需要传递的参数进行拼装
  /// 返回格式为 {params:String} 将Map<T>类型的params json序列化传递出去
  static Future<dynamic> _navigateTo(
    BuildContext context,
    String path, {
    bool replace = false,
    bool clearStack = false,
    Map<String, dynamic>? params,
    TransitionType transition = TransitionType.cupertino,
  }) async {
    final com = Completer();
    Future future = com.future;
    try {
      FocusScope.of(context).requestFocus(FocusNode());
      // 导航栈下标计数
      _navigationStackIndexPlus(replace, clearStack);
      path = _routerNameMixWithParams(path, params);
      // 只有pop执行时, 才会给出明确状态的Future<res>,否则 该await将会一直等待,
      Map<String, dynamic> res = await router.navigateTo(context, path, replace: replace, clearStack: clearStack, transition: transition);
      com.complete(res); // 这一行的执行, 就需要等到下级页面pop了, 才能被触发. 在此之前, await会一直等待,(在页面跳转的时候,确实需要一个同步操作来保证)
    } catch (e) {
      // 撤销计数
      _navigationStackIndexMinus(replace, clearStack);
      com.complete(false); // 跳转失败,也resolve一个false, 方便外部不用每个调用都要catch异常处理, 只需要知道返回False 意味着跳转失败即可
    }
    return future;
  }

  /// 获取当前路由栈的栈顶下标
  static getNavigationStackIndex() {
    return _navigationStackIndex;
  }

  /// push
  /// [path] 目标路由名
  /// [transition] 切换动画类型
  /// [params] push时. 可以传递一些信息给下级页面
  static push(BuildContext context, String path, {Map<String, dynamic>? params, TransitionType transition = TransitionType.cupertino}) {
    debugPrint('push前, 当前路由index = ${_navigationStackIndex.toString()} | (传递的参数为${params.toString()})');
    return _navigateTo(context, path, params: params, replace: false, clearStack: false, transition: transition);
  }

  /// pop
  ///[params] pop时, 可以携带一些信息返回给上级页面
  static pop(BuildContext context, {Map<String, dynamic>? params}) {
    debugPrint('pop前, 当前路由index = ${_navigationStackIndex.toString()} | (回传的参数为${params.toString()})');
    // 导航栈拦截判断是否允许pop
    if (_navigationStackIndex == 0) {
      debugPrint('===== 检测到路由栈已到栈底,阻止pop行为 ======');
      return;
    }
    // 允许pop - 栈内路由数删除1
    if (_navigationStackIndex > 0) {
      _navigationStackIndex -= 1;
    }
    // 允许pop - 执行po操作
    FocusScope.of(context).requestFocus(FocusNode());
    Navigator.pop(context, params ?? {});
    debugPrint('pop后, 当前路由index ' + _navigationStackIndex.toString());
  }

  /// replace
  /// [path] 目标路由名
  /// [transition] 切换动画类型
  /// 跳转到新的路由页面,同时清除当前被跳转的路由
  static replace(BuildContext context, String path, {TransitionType transition = TransitionType.cupertino}) {
    debugPrint('replace前, 当前路由index = ${_navigationStackIndex.toString()} ');
    return _navigateTo(context, path, replace: true, clearStack: false, transition: transition);
  }

  /// clearStack
  /// [path] 目标路由名
  /// [transition] 切换动画类型
  /// 跳转到新的路由页面,同时清空当前路由栈
  static clearStackAndEarlier(BuildContext context, String path, {TransitionType transition = TransitionType.cupertino}) {
    debugPrint('clearStack前, 当前路由index = ${_navigationStackIndex.toString()}');
    return _navigateTo(context, path, replace: false, clearStack: true, transition: transition);
  }
}
